package org.mimizet;

import org.apache.commons.lang.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

/**
 * User: Admin
 * Date: 29.08.11
 * Time: 0:28
 */
public class FSStorage extends Storage {
    File rootFolder;

    FSNamingRule namingRule = new FSNamingRule();

    public FSStorage(Serializer serializer, File rootFolder) {
        super(serializer);

        this.rootFolder = rootFolder;
    }

    class FSNamingRule {
        public File getClassFolder(MethodCall methodCall) {
            String folderName = StringUtils.substringAfterLast(methodCall.className, ".");

            File classFolder = new File(rootFolder, folderName);
            if (!classFolder.exists()) {
                if (!classFolder.mkdir()) {
                    throw new RuntimeException("unable to create folder: " + classFolder.getAbsolutePath());
                }
            }
            return classFolder;
        }
    }

    public void store(MethodCall methodCall) {
        try {
            ConversionResult conversionResult = null;
            if(!"".equals(methodCall.resultConverterClass)){
                conversionResult = methodCall.packResult((Converter) Class.forName(methodCall.resultConverterClass).newInstance());
            }
            serializer.serialize(methodCall, new FileOutputStream(
                    new File(
                            namingRule.getClassFolder(methodCall),
                            getFilename(methodCall)
                    )
            ));


            if(conversionResult != null){
                methodCall.result = conversionResult.restoredFrom;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private String getFilename(MethodCall methodCall) {
        return getSafeFileName(methodCall.toString()) + ".xml";
    }

    public boolean findMethodCall(MethodCall methodCall) {
        try {
            File methodFile = new File(namingRule.getClassFolder(methodCall), getFilename(methodCall));

            if(methodFile.exists()){
                methodCall.result = serializer.deserialize(new FileInputStream(methodFile), MethodCall.class).result;
                
                if(!"".equals(methodCall.resultConverterClass)){
                	methodCall.unpackResult((Converter) Class.forName(methodCall.resultConverterClass).newInstance());                	
                }
                
                return true;
            }

            return false;
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }

    public static String getSafeFileName(String str){
        return str.replaceAll("[/\\n\\r\\t\\f`?*\\\\<>|\\\":]", "");
    }
}
